import enum
import os.path
from typing import List

from pydantic import BaseSettings, BaseModel, Field, validator


class MySQLConfig(BaseModel):
    user: str
    password: str
    database: str
    host: str = Field("localhost")
    port: int = Field(3306)


class RedisConfig(BaseModel):
    password: str = Field(None)
    host: str = Field("localhost")
    port: int = Field(6379)


class JWTConfig(BaseModel):
    tenant_secret: str
    client_secret: str
    admin_secret: str
    algorithms: str
    timeout: int


class AuthWhiteConfig(BaseModel):
    white_path_list: str = Field(default=[], description="认证白名单列表")
    white_path_prefix_tuple: str = Field(default=tuple(), description="认证白名单前缀元组")
    tenant_white_path_list: str = Field(default=[], description="租户端接口不需要tenant header的白名单")

    @validator("white_path_list", "tenant_white_path_list")
    def validate_white_path_list(cls, value):
        return [i for i in value.split(",") if i]

    @validator("white_path_prefix_tuple")
    def validate_white_path_prefix_tuple(cls, value):
        res = tuple(i for i in tuple(value.split(",")) if i)
        return res



class EnvEnum(enum.Enum):
    local = "local"
    dev = "dev"
    test = "test"
    uat = "uat"
    prod = "prod"


class IdWorkerConfig(BaseModel):
    worker_id_bit: int
    data_center_id_bit: int
    sys_starttimestamp: int
    sequence_bit: int


class RabbitMQConfig(BaseModel):
    username: str
    password: str
    host: str
    port: int = Field(None)
    vhost: str = Field(None)


class ESConfig(BaseModel):
    hosts: List[str] = Field(..., description="es链接信息")


class Settings(BaseSettings):
    env: EnvEnum = Field(EnvEnum.local, description="当前环境")
    pj_path: str = Field(None, description="当前项目目录")
    static_root: str = Field(..., description="静态文件路径")
    log_level: str = Field("DEBUG", description="日志文件等级")
    log_path: str = Field(..., description="项目日志文件所在目录")
    mysql_config: MySQLConfig = Field(None, description="mysql配置")
    redis_config: RedisConfig = Field(None, description="redis配置")
    apscheduler_redis_config: RedisConfig = Field(None, description="apscheduler的redis配置")
    jwt_config: JWTConfig = Field(..., description="jwt配置")
    # auth_white_config: AuthWhiteConfig = Field(..., description="jwt认证白名单配置")
    id_worker_config: IdWorkerConfig = Field(..., description="id生成器配置")
    rabbitmq_config: RabbitMQConfig = Field(..., description="队列配置信息")
    es_config: ESConfig = Field(..., description="es配置文件")
    @validator("log_path", "static_root")
    def validate_log_path(cls, value: str, values: dict, config, field: str):
        pj_path = values.get("pj_path")
        if value.startswith("/"):
            p = value
        else:
            p = f"{pj_path}/{value}"
        if not os.path.exists(p):
            os.makedirs(p)
        return p

